#include"../mqserver/mq_virtualhost.hpp"
#include<gtest/gtest.h>


std::unordered_map<std::string,std::string> tmpmap = {{"k1","v1"},{"k2","v2"}};
class HostTest : public testing::Test{
    public:
        void SetUp() override{

            hostp = std::make_shared<mq::Virtualhost>("host1","./data/message","./data/host1.db");
            hostp->declareExchange("exchange1",mq::ExchangeType::DIRECT,true,false,tmpmap);
            hostp->declareExchange("exchange2",mq::ExchangeType::DIRECT,true,false,std::unordered_map<std::string,std::string>());
            hostp->declareExchange("exchange3",mq::ExchangeType::DIRECT,true,false,std::unordered_map<std::string,std::string>());

            hostp->declareQueue("queue1",true,false,false,tmpmap);
            hostp->declareQueue("queue2",true,false,false,std::unordered_map<std::string,std::string>());
            hostp->declareQueue("queue3",true,false,false,std::unordered_map<std::string,std::string>());

            hostp->bind("exchange1","queue1","news.music.#");
            hostp->bind("exchange1","queue2","news.music.#");
            hostp->bind("exchange1","queue3","news.music.#");

            hostp->bind("exchange2","queue1","news.music.#");
            hostp->bind("exchange2","queue2","news.music.#");
            hostp->bind("exchange2","queue3","news.music.#");

            hostp->bind("exchange3","queue1","news.music.#");
            hostp->bind("exchange3","queue2","news.music.#");
            hostp->bind("exchange3","queue3","news.music.#");

            hostp->basicPublish("queue1",nullptr,"hello-world-1");
            hostp->basicPublish("queue1",nullptr,"hello-world-2");
            hostp->basicPublish("queue1",nullptr,"hello-world-3");

            hostp->basicPublish("queue2",nullptr,"hello-world-1");
            hostp->basicPublish("queue2",nullptr,"hello-world-2");
            hostp->basicPublish("queue2",nullptr,"hello-world-3");

            hostp->basicPublish("queue3",nullptr,"hello-world-1");
            hostp->basicPublish("queue3",nullptr,"hello-world-2");
            hostp->basicPublish("queue3",nullptr,"hello-world-3");

            // std::cout<<"create file success"<<std::endl;
        }
        void TearDown() override{
            // std::cout<<"clear..."<<std::endl;
            hostp->clear();
        }
    public:
        mq::Virtualhost::ptr hostp;

};


TEST_F(HostTest,init_test){
    mq::Exchange::ptr ep = hostp->getExchange("exchange1");
    ASSERT_NE(ep.get(),nullptr);
    mq::Exchange::ptr ep2 = hostp->getExchange("exchange2");
    ASSERT_NE(ep2.get(),nullptr);
    mq::Exchange::ptr ep3 = hostp->getExchange("exchange3");
    ASSERT_NE(ep3.get(),nullptr);

    mq::MsgQueueBindMap bindmap =  hostp->exchangeBings("exchange1");
    ASSERT_EQ(bindmap.size(),3);
    mq::MsgQueueBindMap bindmap2 =  hostp->exchangeBings("exchange2");
    ASSERT_EQ(bindmap2.size(),3);
    mq::MsgQueueBindMap bindmap3 =  hostp->exchangeBings("exchange3");
    ASSERT_EQ(bindmap3.size(),3);

    mq::MessagePtr msg = hostp->consume("queue1");
    ASSERT_EQ(msg->payload().body(),"hello-world-1");
    mq::MessagePtr msg2 = hostp->consume("queue1");
    ASSERT_EQ(msg2->payload().body(),"hello-world-2");    
    mq::MessagePtr msg3 = hostp->consume("queue1");
    ASSERT_EQ(msg3->payload().body(),"hello-world-3");    
    
    mq::MessagePtr msg4 = hostp->consume("queue1");
    ASSERT_EQ(msg4.get(),nullptr);
    mq::MessagePtr msg5 = hostp->consume("queue4");
    ASSERT_EQ(msg5.get(),nullptr);

}

TEST_F(HostTest,destroyexchange_test){
    hostp->unBind("exchange1","queue1");
    mq::MsgQueueBindMap qbmp = hostp->exchangeBings("exchange1");
    ASSERT_EQ(qbmp.size(),2);

    hostp->unBind("exchange1","queue2");
    mq::MsgQueueBindMap qbmp2 = hostp->exchangeBings("exchange1");
    ASSERT_EQ(qbmp2.size(),1);

    hostp->unBind("exchange1","queue3");
    mq::MsgQueueBindMap qbmp3 = hostp->exchangeBings("exchange1");
    ASSERT_EQ(qbmp3.size(),0);

    hostp->deleteExchange("exchange1");
    mq::Exchange::ptr e =hostp->getExchange("exchange1");
    ASSERT_EQ(e.get(),nullptr);
}

TEST_F(HostTest,ack_test){
    mq::MessagePtr msg = hostp->consume("queue1");
    ASSERT_EQ(msg->payload().body(),"hello-world-1");
    hostp->basicAck("queue1",msg->payload().basepro().id());

    mq::MessagePtr msg2 = hostp->consume("queue1");
    ASSERT_EQ(msg2->payload().body(),"hello-world-2");
    hostp->basicAck("queue1",msg->payload().basepro().id());   

    mq::MessagePtr msg3 = hostp->consume("queue1");
    ASSERT_EQ(msg3->payload().body(),"hello-world-3");
    hostp->basicAck("queue1",msg->payload().basepro().id());

}

TEST_F(HostTest,destroyqueue_test){
    hostp->deleteQueue("queue1");
    mq::MessagePtr msg = hostp->consume("queue1");
    ASSERT_EQ(msg.get(),nullptr);

    mq::MessagePtr msg2 = hostp->consume("queue2");
    ASSERT_EQ(msg2->payload().body(),"hello-world-1");


}

int main(int argc,char* argv[]){
    testing::InitGoogleTest(&argc,argv);
    // testing::AddGlobalTestEnvironment(new HostTest);
    return RUN_ALL_TESTS();
}
